package com.alibaba.cloud.application.handler;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import com.alibaba.cloud.domain.BaseMessage;
import com.alibaba.cloud.domain.EmailLog;
import com.alibaba.cloud.domain.EmailMessage;
import com.alibaba.cloud.infrastructure.mapper.EmailLogMapper;

import freemarker.template.Configuration;
import freemarker.template.Template;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author cruise
 */
@RequiredArgsConstructor
@Slf4j
@Component
public class EmailMessageHandler extends BaseMessageHandler {
    private final EmailLogMapper emailLogMapper;
    private final JavaMailSender mailSender;
    private final Configuration configuration;
    @Value("${spring.mail.username}")
    public String USER_NAME;
    @Value("${server.path}")
    public String PATH;
    static {
        System.setProperty("mail.mime.splitlongparameters", "false");
    }

    @Override
    public void send(BaseMessage message) {
        if (interestedMessage(message)) {
            if (StringUtils.isBlank(message.getTemplate())) {
                sendSimple((EmailMessage) message);
            } else {
                sendTemplate((EmailMessage) message);
            }
        }
    }

    @Override
    public void record(BaseMessage message) {
        EmailMessage emailMessage = (EmailMessage) message;
        EmailLog emailLog = EmailLog.builder()
                .receive(emailMessage.getReceive())
                .sendTime(LocalDateTime.now())
                .content(emailMessage.getContent())
                .template(emailMessage.getTemplate())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .creator("system")
                .subject(emailMessage.getSubject()).build();
        emailLogMapper.insert(emailLog);
    }

    @Override
    public boolean interestedMessage(BaseMessage message) {
        if (message instanceof EmailMessage) {
            return true;
        }
        return false;
    }

    private void sendSimple(EmailMessage emailMessage) {
        log.info("发送邮件：{}", emailMessage);
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(USER_NAME);
            message.setTo(emailMessage.getReceive());
            message.setSubject(emailMessage.getSubject());
            message.setText(emailMessage.getContent());
            mailSender.send(message);
            // 发送记录
            record(emailMessage);
        } catch (Exception e) {
            log.error("邮件：{}，发送失败,", emailMessage, e);
            //throw new MessageSendException(ResultCodeEnum.EMAIL_SEND_FAIL, ResultCodeEnum.EMAIL_SEND_FAIL.desc());
        }
    }

    private void sendTemplate(EmailMessage emailMessage) {
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            // 这里可以自定义发信名称比如：爪哇笔记
            helper.setFrom(USER_NAME, "汤姆克鲁斯");
            helper.setTo(emailMessage.getReceive());
            helper.setSubject(emailMessage.getSubject());
            Map<String, Object> model = new HashMap<>();
            model.put("content", emailMessage.getContent());
            model.put("path", PATH);
            Template template = configuration.getTemplate(emailMessage.getTemplate());
            String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
            helper.setText(text, true);
            mailSender.send(message);
            emailMessage.setContent(text);
            // 发送记录
            record(emailMessage);
        } catch (Exception e) {
            log.error("邮件：{} 发送失败", emailMessage, e);
            //throw new MessageSendException(ResultCodeEnum.EMAIL_SEND_FAIL, ResultCodeEnum.EMAIL_SEND_FAIL.desc());
        }
    }

}
